#ifndef HASHROWSYNCHRONIZEDIMPL_H_JM_20120910
#define HASHROWSYNCHRONIZEDIMPL_H_JM_20120910

//#include <boost/thread/mutex.hpp>
//#include <tbb/mutex.h>
//#include "upp_mthr.hpp"

#include "HashRow.h"


namespace jmlib {

	template<class KeyT, class ValueT, class MutexT, class ScopedLockT>
	class HashRowSynchronizedImpl : public HashRow<KeyT, ValueT>{
	public:		

		HashRowSynchronizedImpl() : hashRow_(nullptr) { }
		
		void setHashRowUnsynchronized(HashRowInterface* hashRow) { 
			hashRow_ = hashRow; 
		}

		virtual int add(const KeyType& key, const ValueType& value) override {
			scopeLockType lock(mutex_);
			return hashRow_->add(key, value);
		}
	
		virtual bool hasKey(const KeyType& key) const  override {
			scopeLockType lock(mutex_);
			return hashRow_->hasKey(key);
		}

		virtual bool addIf(const KeyType& key, const ValueType& value, 
			const HashRowActionCondition& cond) override {
				scopeLockType lock(mutex_);
				return hashRow_->addIf(key, value, cond);
		}

		virtual bool remove(const KeyType& key) override {
			scopeLockType lock(mutex_);
			return hashRow_->remove(key);		
		}

		ExtendedRowEntry getExtendedValue(const size_t& index) const {
			scopeLockType lock(mutex_);
			return hashRow_->getExtendedValue(index);
		}

		bool isEmpty() const {
			scopeLockType lock(mutex_);
			return hashRow_->isEmpty();
		}

		void clear() {
			scopeLockType lock(mutex_);
			hashRow_->clear();
		}

		virtual size_t getExtendedEntryCount() const override {
			scopeLockType lock(mutex_);
			return hashRow_->getExtendedEntryCount();
		}
		virtual size_t getAggregatedEntryCount() const override {
			scopeLockType lock(mutex_);
			return hashRow_->getAggregatedEntryCount();
		}

		virtual void foreach(ForechEntryFunType functor) override {
			scopeLockType lock(mutex_);
			hashRow_->foreach(functor);
		}

		virtual void foreachExtended(ForechExtendedEntryFunType functor) override {
			scopeLockType lock(mutex_);
			hashRow_->foreachExtended(functor);
		}

		virtual bool applyOn(ForechEntryFunType functor, const KeyType& key) override {
			scopeLockType lock(mutex_);
			return hashRow_->applyOn(functor, key);
		}

		virtual bool applyOnExtended(ForechExtendedEntryFunType functor, 
			const KeyType& key) override {
				scopeLockType lock(mutex_);
				return hashRow_->applyOnExtended(functor, key);
		}

		virtual HashRowInterface* getLockFreeInstance() {
			return hashRow_->getLockFreeInstance();
		};
		
		virtual HashRowInterface* getLockableInstance() {
			return this;
		};

	private:
		typedef MutexT mutexType;
		typedef ScopedLockT scopeLockType;

		HashRowInterface* hashRow_;
		mutable mutexType mutex_;
		
	};
	
} // namespace jmlib

#endif
